/*
 * Utility.java
 *
 * Created on 29 March 2012, 11:14
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package Simulation.Utils;

import java.nio.ByteBuffer;
import java.util.Arrays;
/**
 *
 * @author aking2
 */

public class ByteArrayUtils {
    
    public static byte[] subBytes(byte[] b, int start, int len) {
        return Arrays.copyOfRange(b, start, start+len); 
    }
    
    // Start is 0 for LSB
    public static int BitsToInt(int value, int start, int len) {
        int result = value >> start;
        int mask   = 0xFF  >> 8-len;
        result = result & mask;
        return result;
    }    
    
    public static int bitMask(int start, int len) {
        // count unused bits on MSB side
        int msbUnused = 8 - (start + len);        
        // clear unused bits on MSB side
        int mask = ((0xFF << msbUnused) & 0xFF) >> msbUnused;        
        // clear unused bits on LSB side
        mask = (mask >> start) << start;        
        return mask;
    }
    
    public static byte[] IntToBits(int value, int start, int len, int background) {
        int mask   = bitMask(start,len);
        int result = (value << start) & mask;
        // or the result into the rest of the bits in the byte. These
        // are passed in as background.
        int clearedBackGround = background & (~mask);                
        result = result | clearedBackGround;
        byte[] wrapper = new byte[1];
        wrapper[0] = (byte) result;
        return wrapper;
    }        
    
    public static byte BytesToByte( byte[] b) {
        // if we just straight cast this to
        
        return b[0];
    }
    
    public static int UnsignNumber( byte n) {
        int result = (int) n;
        if( result < 0) {
            result *= -1;
            result = result | 0x80;
        }
        return result;
    }
    
    public static int UnsignNumber( short n) {
        int result = (int) n;
        if( result < 0) {
            result *= -1;
            result = result | 0x8000;
        }
        return result;
    }         
    
    public static short BytesToShort( byte[] b) {
        ByteBuffer bb = ByteBuffer.wrap(b);  
        return bb.asShortBuffer().get();
    }  
    
    public static int BytesToInt( byte[] b) {
        ByteBuffer bb = ByteBuffer.wrap(b);  
        return bb.asIntBuffer().get();
    }   
    
    public static long BytesToLong( byte[] incomingBytes) {        
        // All this monkeying about is to remove the unwanted sign bit.
        // Note that jaca is big endian. MSB is at lowest address.
        byte[] outgoingBytes = new byte[8];
        ByteBuffer outgoingByteBuffer = ByteBuffer.wrap(outgoingBytes);          
        for( int i=0; i<8; i++){
            outgoingBytes[i] = 0;
        }        
        
        int to = 8-incomingBytes.length;
        for( int from=0; from<incomingBytes.length; from++, to++){
            outgoingBytes[to] = incomingBytes[from];
        }
                
        return outgoingByteBuffer.asLongBuffer().get();        
    }       
    
    public static float BytesToFloat( byte[] b) {
        ByteBuffer bb = ByteBuffer.wrap(b);  
        return bb.asFloatBuffer().get();
    }
       
    public static double BytesToDouble( byte[] b) {
        ByteBuffer bb = ByteBuffer.wrap(b);  
        return bb.asDoubleBuffer().get();
    }  
    
    public static byte[] ToByte( byte value) {
        byte[] bytes = new byte[1];
        bytes[0] = (byte) value;
        return bytes;
    }
    
    public static byte[] ToByte( short value) {
        byte[] bytes = new byte[2];
        ByteBuffer bb = ByteBuffer.wrap(bytes);  
        bb.asShortBuffer().put(value);
        return bytes;
    }    
    
    public static byte[] ToByte( int value) {
        byte[] bytes = new byte[4];
        ByteBuffer bb = ByteBuffer.wrap(bytes);  
        bb.asIntBuffer().put(value);
        return bytes;
    }    
    
    public static byte[] ToByte( long value) {
        byte[] bytes = new byte[8];
        ByteBuffer bb = ByteBuffer.wrap(bytes);  
        bb.asLongBuffer().put(value);
        return bytes;
    }      
    
    public static byte[] ToByte( float value) {
       byte[] bytes = new byte[4];
        ByteBuffer bb = ByteBuffer.wrap(bytes);  
        bb.asFloatBuffer().put(value);
        return bytes;
    }        
    
    public static byte[] ToByte( double value) {
       byte[] bytes = new byte[8];
        ByteBuffer bb = ByteBuffer.wrap(bytes);  
        bb.asDoubleBuffer().put(value);
        return bytes;
    }       
    
}
